static string JS_server_ahuacatl = 
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief Ahuacatl, internal query functions \n"
  "///\n"
  "/// @file\n"
  "///\n"
  "/// DISCLAIMER\n"
  "///\n"
  "/// Copyright 2010-2012 triagens GmbH, Cologne, Germany\n"
  "///\n"
  "/// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
  "/// you may not use this file except in compliance with the License.\n"
  "/// You may obtain a copy of the License at\n"
  "///\n"
  "///     http://www.apache.org/licenses/LICENSE-2.0\n"
  "///\n"
  "/// Unless required by applicable law or agreed to in writing, software\n"
  "/// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
  "/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
  "/// See the License for the specific language governing permissions and\n"
  "/// limitations under the License.\n"
  "///\n"
  "/// Copyright holder is triAGENS GmbH, Cologne, Germany\n"
  "///\n"
  "/// @author Jan Steemann\n"
  "/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief type weight used for sorting and comparing\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "var AHUACATL_TYPEWEIGHT_NULL      = 0;\n"
  "var AHUACATL_TYPEWEIGHT_BOOL      = 1;\n"
  "var AHUACATL_TYPEWEIGHT_NUMBER    = 2;\n"
  "var AHUACATL_TYPEWEIGHT_STRING    = 4;\n"
  "var AHUACATL_TYPEWEIGHT_LIST      = 8;\n"
  "var AHUACATL_TYPEWEIGHT_DOCUMENT  = 16;\n"
  "\n"
  "// -----------------------------------------------------------------------------\n"
  "// --SECTION--                                                  helper functions\n"
  "// -----------------------------------------------------------------------------\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @addtogroup Ahuacatl\n"
  "/// @{\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief clone an object\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_CLONE (obj) {\n"
  "  if (obj == null || typeof obj != \"object\") {\n"
  "    return obj;\n"
  "  }\n"
  "\n"
  "  if (obj instanceof Array) {\n"
  "    var copy = [];\n"
  "    var length = obj.length;\n"
  "    for (var i = 0; i < length; ++i) {\n"
  "      copy[i] = AHUACATL_CLONE(obj[i]);\n"
  "    }\n"
  "    return copy;\n"
  "  }\n"
  "\n"
  "  if (obj instanceof Object) {\n"
  "    var copy = {};\n"
  "    for (var attr in obj) {\n"
  "      if (obj.hasOwnProperty(attr)) {\n"
  "        copy[attr] = AHUACATL_CLONE(obj[attr]);\n"
  "      }\n"
  "    }\n"
  "    return copy;\n"
  "  }\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief call a function\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_FCALL(name, parameters) {\n"
  "  return name(parameters);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief get the value of a bind parameter\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_GET_PARAMETER (name) {\n"
  "  throw \"bind parameters not yet supported\";\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief return the numeric value or undefined if it is out of range\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_NUMERIC_VALUE (value) {\n"
  "  if (isNaN(value) || !isFinite(value)) {\n"
  "    return null;\n"
  "  }\n"
  "\n"
  "  return value;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief get the sort type of an operand\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_TYPEWEIGHT (value) {\n"
  "  if (value === undefined || value === null) {\n"
  "    return AHUACATL_TYPEWEIGHT_NULL;\n"
  "  }\n"
  "\n"
  "  if (value instanceof Array) {\n"
  "    return AHUACATL_TYPEWEIGHT_LIST;\n"
  "  }\n"
  "\n"
  "  switch (typeof(value)) {\n"
  "    case 'boolean':\n"
  "      return AHUACATL_TYPEWEIGHT_BOOL;\n"
  "    case 'number':\n"
  "      if (isNaN(value) || !isFinite(value)) {\n"
  "        // not a number => undefined\n"
  "        return AHUACATL_TYPEWEIGHT_NULL; \n"
  "      }\n"
  "      return AHUACATL_TYPEWEIGHT_NUMBER;\n"
  "    case 'string':\n"
  "      return AHUACATL_TYPEWEIGHT_STRING;\n"
  "    case 'object':\n"
  "      return AHUACATL_TYPEWEIGHT_DOCUMENT;\n"
  "  }\n"
  "\n"
  "  return AHUACATL_TYPEWEIGHT_NULL;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief get the keys of an array or object in a comparable way\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_KEYS (value) {\n"
  "  var keys = [];\n"
  "  \n"
  "  if (value instanceof Array) {\n"
  "    var i = 0;\n"
  "    for (var k in value) {\n"
  "      if (value.hasOwnProperty(k)) {\n"
  "        keys.push(i++);\n"
  "      }\n"
  "    }\n"
  "  }\n"
  "  else {\n"
  "    for (var k in value) {\n"
  "      if (value.hasOwnProperty(k)) {\n"
  "        keys.push(k);\n"
  "      }\n"
  "    }\n"
  "\n"
  "    // object keys need to be sorted by names\n"
  "    keys.sort();\n"
  "  }\n"
  "\n"
  "  return keys;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief get an indexed value from an array or document (e.g. users[3])\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_GET_INDEX (value, index) {\n"
  "  if (AHUACATL_TYPEWEIGHT(value) == AHUACATL_TYPEWEIGHT_NULL) {\n"
  "    return null;\n"
  "  }\n"
  "  \n"
  "  if (AHUACATL_TYPEWEIGHT(value) != AHUACATL_TYPEWEIGHT_LIST &&\n"
  "      AHUACATL_TYPEWEIGHT(value) != AHUACATL_TYPEWEIGHT_DOCUMENT) {\n"
  "    throw \"expecting list or document for index access\";\n"
  "  }\n"
  "\n"
  "  var result = value[attributeName];\n"
  "\n"
  "  if (AHUACATL_TYPEWEIGHT(result) === AHUACATL_TYPEWEIGHT_NULL) {\n"
  "    return null;\n"
  "  }\n"
  "\n"
  "  return result;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief get an attribute from a document (e.g. users.name)\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_DOCUMENT_MEMBER (value, attributeName) {\n"
  "  if (AHUACATL_TYPEWEIGHT(value) == AHUACATL_TYPEWEIGHT_NULL) {\n"
  "    return null;\n"
  "  }\n"
  "\n"
  "  if (AHUACATL_TYPEWEIGHT(value) != AHUACATL_TYPEWEIGHT_DOCUMENT) {\n"
  "    throw \"expecting document for member access\";\n"
  "  }\n"
  "\n"
  "  var result = value[attributeName];\n"
  "\n"
  "  if (AHUACATL_TYPEWEIGHT(result) === AHUACATL_TYPEWEIGHT_NULL) {\n"
  "    return null;\n"
  "  }\n"
  "\n"
  "  return result;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief assert that a value is a list, fail otherwise\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_LIST (value) {\n"
  "  if (AHUACATL_TYPEWEIGHT(value) !== AHUACATL_TYPEWEIGHT_LIST) {\n"
  "    throw \"expecting list\";\n"
  "  }\n"
  "\n"
  "  return value;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief get documents from the specified collection\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_GET_DOCUMENTS (collection) {\n"
  "  return internal.db[collection].all().toArray();\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @}\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "// -----------------------------------------------------------------------------\n"
  "// --SECTION--                                                logical operations\n"
  "// -----------------------------------------------------------------------------\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @addtogroup Ahuacatl\n"
  "/// @{\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform logical and\n"
  "///\n"
  "/// both operands must be boolean values, returns a boolean, uses short-circuit\n"
  "/// evaluation\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_LOGICAL_AND (lhs, rhs) {\n"
  "  if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_BOOL ||\n"
  "      AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_BOOL) {\n"
  "    throw \"expecting bool operands for and\";\n"
  "  }\n"
  "\n"
  "  if (!lhs) {\n"
  "    return false;\n"
  "  }\n"
  "\n"
  "  return rhs;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform logical or\n"
  "///\n"
  "/// both operands must be boolean values, returns a boolean, uses short-circuit\n"
  "/// evaluation\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_LOGICAL_OR (lhs, rhs) {\n"
  "  if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_BOOL ||\n"
  "      AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_BOOL) {\n"
  "    throw \"expecting bool operands for or\";\n"
  "  }\n"
  "  \n"
  "  if (lhs) {\n"
  "    return true;\n"
  "  }\n"
  "\n"
  "  return rhs;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform logical negation\n"
  "///\n"
  "/// the operand must be a boolean values, returns a boolean\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_LOGICAL_NOT (lhs) {\n"
  "  if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_BOOL) {\n"
  "    throw \"expecting bool operand for not\";\n"
  "  }\n"
  "\n"
  "  return !lhs;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @}\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "// -----------------------------------------------------------------------------\n"
  "// --SECTION--                                             comparison operations\n"
  "// -----------------------------------------------------------------------------\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @addtogroup Ahuacatl\n"
  "/// @{\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform equality check \n"
  "///\n"
  "/// returns true if the operands are equal, false otherwise\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_RELATIONAL_EQUAL (lhs, rhs) {\n"
  "  var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
  "  var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
  "\n"
  "  if (leftWeight != rightWeight) {\n"
  "    return false;\n"
  "  }\n"
  "\n"
  "  // lhs and rhs have the same type\n"
  "\n"
  "  if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
  "    // arrays and objects\n"
  "    var l = AHUACATL_KEYS(lhs);\n"
  "    var r = AHUACATL_KEYS(rhs);\n"
  "    var numLeft = l.length;\n"
  "    var numRight = r.length;\n"
  "\n"
  "    if (numLeft !== numRight) {\n"
  "      return false;\n"
  "    }\n"
  "\n"
  "    for (var i = 0; i < numLeft; ++i) {\n"
  "      var key = l[i];\n"
  "      if (key !== r[i]) {\n"
  "        // keys must be identical\n"
  "        return false;\n"
  "      }\n"
  "\n"
  "      var result = AHUACATL_RELATIONAL_EQUAL(lhs[key], rhs[key]);\n"
  "      if (result === false) {\n"
  "        return result;\n"
  "      }\n"
  "    }\n"
  "    return true;\n"
  "  }\n"
  "\n"
  "  // primitive type\n"
  "  return (lhs === rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform inequality check \n"
  "///\n"
  "/// returns true if the operands are unequal, false otherwise\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_RELATIONAL_UNEQUAL (lhs, rhs) {\n"
  "  var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
  "  var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
  "  \n"
  "  if (leftWeight != rightWeight) {\n"
  "    return true;\n"
  "  }\n"
  "\n"
  "  // lhs and rhs have the same type\n"
  "\n"
  "  if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
  "    // arrays and objects\n"
  "    var l = AHUACATL_KEYS(lhs);\n"
  "    var r = AHUACATL_KEYS(rhs);\n"
  "    var numLeft = l.length;\n"
  "    var numRight = r.length;\n"
  "\n"
  "    if (numLeft !== numRight) {\n"
  "      return true;\n"
  "    }\n"
  "\n"
  "    for (var i = 0; i < numLeft; ++i) {\n"
  "      var key = l[i];\n"
  "      if (key !== r[i]) {\n"
  "        // keys differ => unequality\n"
  "        return true;\n"
  "      }\n"
  "\n"
  "      var result = AHUACATL_RELATIONAL_UNEQUAL(lhs[key], rhs[key]);\n"
  "      if (result === true) {\n"
  "        return result;\n"
  "      }\n"
  "    }\n"
  "\n"
  "    return false;\n"
  "  }\n"
  "\n"
  "  // primitive type\n"
  "  return (lhs !== rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform greater than check (inner function)\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_RELATIONAL_GREATER_REC (lhs, rhs) {\n"
  "  var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
  "  var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
  "  \n"
  "  if (leftWeight > rightWeight) {\n"
  "    return true;\n"
  "  }\n"
  "  if (leftWeight < rightWeight) {\n"
  "    return false;\n"
  "  }\n"
  "\n"
  "  // lhs and rhs have the same type\n"
  "\n"
  "  if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
  "    // arrays and objects\n"
  "    var l = AHUACATL_KEYS(lhs);\n"
  "    var r = AHUACATL_KEYS(rhs);\n"
  "    var numLeft = l.length;\n"
  "    var numRight = r.length;\n"
  "\n"
  "    for (var i = 0; i < numLeft; ++i) {\n"
  "      if (i >= numRight) {\n"
  "        // right operand does not have any more keys\n"
  "        return true;\n"
  "      }\n"
  "      var key = l[i];\n"
  "      if (key < r[i]) {\n"
  "        // left key is less than right key\n"
  "        return true;\n"
  "      } \n"
  "      else if (key > r[i]) {\n"
  "        // left key is bigger than right key\n"
  "        return false;\n"
  "      }\n"
  "\n"
  "      var result = AHUACATL_RELATIONAL_GREATER_REC(lhs[key], rhs[key]);\n"
  "      if (result !== null) {\n"
  "        return result;\n"
  "      }\n"
  "    }\n"
  "    \n"
  "    if (numRight > numLeft) {\n"
  "      return false;\n"
  "    }\n"
  "\n"
  "    return null;\n"
  "  }\n"
  "\n"
  "  // primitive type\n"
  "  if (lhs === rhs) {\n"
  "    return null;\n"
  "  }\n"
  "\n"
  "  return (lhs > rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform greater than check \n"
  "///\n"
  "/// returns true if the left operand is greater than the right operand\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_RELATIONAL_GREATER (lhs, rhs) {\n"
  "  var result = AHUACATL_RELATIONAL_GREATER_REC(lhs, rhs);\n"
  "\n"
  "  if (result === null) {\n"
  "    result = false;\n"
  "  }\n"
  "\n"
  "  return result;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform greater equal check (inner function)\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_RELATIONAL_GREATEREQUAL_REC (lhs, rhs) {\n"
  "  var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
  "  var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
  "  \n"
  "  if (leftWeight > rightWeight) {\n"
  "    return true;\n"
  "  }\n"
  "  if (leftWeight < rightWeight) {\n"
  "    return false;\n"
  "  }\n"
  "\n"
  "  // lhs and rhs have the same type\n"
  "\n"
  "  if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
  "    // arrays and objects\n"
  "    var l = AHUACATL_KEYS(lhs);\n"
  "    var r = AHUACATL_KEYS(rhs);\n"
  "    var numLeft = l.length;\n"
  "    var numRight = r.length;\n"
  "\n"
  "    for (var i = 0; i < numLeft; ++i) {\n"
  "      if (i >= numRight) {\n"
  "        return true;\n"
  "      }\n"
  "      var key = l[i];\n"
  "      if (key < r[i]) {\n"
  "        // left key is less than right key\n"
  "        return true;\n"
  "      } \n"
  "      else if (key > r[i]) {\n"
  "        // left key is bigger than right key\n"
  "        return false;\n"
  "      }\n"
  "\n"
  "      var result = AHUACATL_RELATIONAL_GREATEREQUAL_REC(lhs[key], rhs[key]);\n"
  "      if (result !== null) {\n"
  "        return result;\n"
  "      }\n"
  "    }\n"
  "    \n"
  "    if (numRight > numLeft) {\n"
  "      return false;\n"
  "    }\n"
  "\n"
  "    return null;\n"
  "  }\n"
  "\n"
  "  // primitive type\n"
  "  if (lhs === rhs) {\n"
  "    return null;\n"
  "  }\n"
  "\n"
  "  return (lhs >= rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform greater equal check \n"
  "///\n"
  "/// returns true if the left operand is greater or equal to the right operand\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_RELATIONAL_GREATEREQUAL (lhs, rhs) {\n"
  "  var result = AHUACATL_RELATIONAL_GREATEREQUAL_REC(lhs, rhs);\n"
  "\n"
  "  if (result === null) {\n"
  "    result = true;\n"
  "  }\n"
  "\n"
  "  return result;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform less than check (inner function)\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_RELATIONAL_LESS_REC (lhs, rhs) {\n"
  "  var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
  "  var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
  "  \n"
  "  if (leftWeight < rightWeight) {\n"
  "    return true;\n"
  "  }\n"
  "  if (leftWeight > rightWeight) {\n"
  "    return false;\n"
  "  }\n"
  "\n"
  "  // lhs and rhs have the same type\n"
  "\n"
  "  if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
  "    // arrays and objects\n"
  "    var l = AHUACATL_KEYS(lhs);\n"
  "    var r = AHUACATL_KEYS(rhs);\n"
  "    var numLeft = l.length;\n"
  "    var numRight = r.length;\n"
  "\n"
  "    for (var i = 0; i < numRight; ++i) {\n"
  "      if (i >= numLeft) {\n"
  "        // left operand does not have any more keys\n"
  "        return true;\n"
  "      }\n"
  "      var key = l[i];\n"
  "      if (key < r[i]) {\n"
  "        // left key is less than right key\n"
  "        return false;\n"
  "      } \n"
  "      else if (key > r[i]) {\n"
  "        // left key is bigger than right key (\"b\", \"a\") {\"b\" : 1}, {\"a\" : 1}\n"
  "        return true;\n"
  "      }\n"
  "      // keys are equal\n"
  "      var result = AHUACATL_RELATIONAL_LESS_REC(lhs[key], rhs[key]);\n"
  "      if (result !== null) {\n"
  "        return result;\n"
  "      }\n"
  "    }\n"
  "    \n"
  "    if (numLeft > numRight) {\n"
  "      return false;\n"
  "    }\n"
  "\n"
  "    return null;\n"
  "  }\n"
  "\n"
  "  // primitive type\n"
  "  if (lhs === rhs) {\n"
  "    return null;\n"
  "  }\n"
  "\n"
  "  return (lhs < rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform less than check \n"
  "///\n"
  "/// returns true if the left operand is less than the right operand\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_RELATIONAL_LESS (lhs, rhs) {\n"
  "  var result = AHUACATL_RELATIONAL_LESS_REC(lhs, rhs);\n"
  "\n"
  "  if (result === null) {\n"
  "    result = false;\n"
  "  }\n"
  "\n"
  "  return result;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform less equal check (inner function)\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_RELATIONAL_LESSEQUAL_REC (lhs, rhs) {\n"
  "  var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
  "  var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
  "  \n"
  "  if (leftWeight < rightWeight) {\n"
  "    return true;\n"
  "  }\n"
  "  if (leftWeight > rightWeight) {\n"
  "    return false;\n"
  "  }\n"
  "\n"
  "  // lhs and rhs have the same type\n"
  "\n"
  "  if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
  "    // arrays and objects\n"
  "    var l = AHUACATL_KEYS(lhs);\n"
  "    var r = AHUACATL_KEYS(rhs);\n"
  "    var numLeft = l.length;\n"
  "    var numRight = r.length;\n"
  "\n"
  "    for (var i = 0; i < numRight; ++i) {\n"
  "      if (i >= numLeft) {\n"
  "        return true;\n"
  "      }\n"
  "      var key = l[i];\n"
  "      if (key < r[i]) {\n"
  "        // left key is less than right key\n"
  "        return false;\n"
  "      } \n"
  "      else if (key > r[i]) {\n"
  "        // left key is bigger than right key\n"
  "        return true;\n"
  "      }\n"
  "      var result = AHUACATL_RELATIONAL_LESSEQUAL_REC(lhs[key], rhs[key]);\n"
  "      if (result !== null) {\n"
  "        return result;\n"
  "      }\n"
  "    }\n"
  "\n"
  "    if (numLeft > numRight) {\n"
  "      return false;\n"
  "    }\n"
  "\n"
  "    return null;\n"
  "  }\n"
  "  \n"
  "  if (lhs === rhs) {\n"
  "    return null;\n"
  "  }\n"
  "\n"
  "  // primitive type\n"
  "  return (lhs <= rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform less equal check \n"
  "///\n"
  "/// returns true if the left operand is less or equal to the right operand\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_RELATIONAL_LESSEQUAL (lhs, rhs) {\n"
  "  var result = AHUACATL_RELATIONAL_LESSEQUAL_REC(lhs, rhs);\n"
  "\n"
  "  if (result === null) {\n"
  "    result = true;\n"
  "  }\n"
  "\n"
  "  return result;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform in list check \n"
  "///\n"
  "/// returns true if the left operand is contained in the right operand\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_RELATIONAL_IN (lhs, rhs) {\n"
  "  var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
  "  var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
  "  \n"
  "  if (rightWeight !== AHUACATL_TYPEWEIGHT_LIST) {\n"
  "    throw \"expecting list for in\";\n"
  "  }\n"
  "  \n"
  "  var r = AHUACATL_KEYS(rhs);\n"
  "  var numRight = r.length;\n"
  "\n"
  "  for (var i = 0; i < numRight; ++i) {\n"
  "    var key = r[i];\n"
  "    if (AHUACATL_RELATIONAL_EQUAL(lhs, rhs[key])) {\n"
  "      return true;\n"
  "    }\n"
  "  }\n"
  "\n"
  "  return false;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @}\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "// -----------------------------------------------------------------------------\n"
  "// --SECTION--                                             arithmetic operations\n"
  "// -----------------------------------------------------------------------------\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @addtogroup Ahuacatl\n"
  "/// @{\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform unary plus operation\n"
  "///\n"
  "/// the operand must be numeric or this function will fail\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_UNARY_PLUS (value) {\n"
  "  if (AHUACATL_TYPEWEIGHT(value) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
  "    throw \"expecting number for unary plus\";\n"
  "  }\n"
  "\n"
  "  return AHUACATL_NUMERIC_VALUE(value);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform unary minus operation\n"
  "///\n"
  "/// the operand must be numeric or this function will fail\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_UNARY_MINUS (value) {\n"
  "  if (AHUACATL_TYPEWEIGHT(value) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
  "    throw \"expecting number for unary minus\";\n"
  "  }\n"
  "\n"
  "  return AHUACATL_NUMERIC_VALUE(-value);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform artithmetic plus\n"
  "///\n"
  "/// both operands must be numeric or this function will fail\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_ARITHMETIC_PLUS (lhs, rhs) { \n"
  "  if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_NUMBER ||\n"
  "      AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
  "    throw \"expecting numbers for plus\";\n"
  "  }\n"
  "\n"
  "  return AHUACATL_NUMERIC_VALUE(lhs + rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform artithmetic minus\n"
  "///\n"
  "/// both operands must be numeric or this function will fail\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_ARITHMETIC_MINUS (lhs, rhs) {\n"
  "  if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_NUMBER ||\n"
  "      AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
  "    throw \"expecting numbers for minus\";\n"
  "  }\n"
  "\n"
  "  return AHUACATL_NUMERIC_VALUE(lhs - rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform artithmetic multiplication\n"
  "///\n"
  "/// both operands must be numeric or this function will fail\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_ARITHMETIC_TIMES (lhs, rhs) {\n"
  "  if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_NUMBER ||\n"
  "      AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
  "    throw \"expecting numbers for times\";\n"
  "  }\n"
  "\n"
  "  return AHUACATL_NUMERIC_VALUE(lhs * rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform artithmetic division\n"
  "///\n"
  "/// both operands must be numeric or this function will fail\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_ARITHMETIC_DIVIDE (lhs, rhs) {\n"
  "  if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_NUMBER ||\n"
  "      AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
  "    throw \"expecting numbers for div\";\n"
  "  }\n"
  "  \n"
  "  if (rhs == 0) {\n"
  "    throw \"division by zero\";\n"
  "  }\n"
  "\n"
  "  return AHUACATL_NUMERIC_VALUE(lhs / rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform artithmetic modulus\n"
  "///\n"
  "/// both operands must be numeric or this function will fail\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_ARITHMETIC_MODULUS (lhs, rhs) {\n"
  "  if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_NUMBER ||\n"
  "      AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
  "    throw \"expecting numbers for mod\";\n"
  "  }\n"
  "\n"
  "  if (rhs == 0) {\n"
  "    throw \"division by zero\";\n"
  "  }\n"
  "\n"
  "  return AHUACATL_NUMERIC_VALUE(lhs % rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @}\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "// -----------------------------------------------------------------------------\n"
  "// --SECTION--                                                  string functions\n"
  "// -----------------------------------------------------------------------------\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @addtogroup Ahuacatl\n"
  "/// @{\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief perform string concatenation\n"
  "///\n"
  "/// both operands must be strings or this function will fail\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_STRING_CONCAT (lhs, rhs) {\n"
  "  if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_STRING ||\n"
  "      AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_STRING) {\n"
  "    throw \"expecting strings for string concatenation\";\n"
  "  }\n"
  "\n"
  "  return (lhs + rhs);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @}\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "// -----------------------------------------------------------------------------\n"
  "// --SECTION--                                                typecast functions\n"
  "// -----------------------------------------------------------------------------\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @addtogroup Ahuacatl\n"
  "/// @{\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief cast to a number\n"
  "///\n"
  "/// the operand can have any type, always returns a number\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_CAST_NUMBER (value) {\n"
  "  switch (AHUACATL_TYPEWEIGHT(value)) {\n"
  "    case AHUACATL_TYPEWEIGHT_NULL:\n"
  "    case AHUACATL_TYPEWEIGHT_LIST:\n"
  "    case AHUACATL_TYPEWEIGHT_DOCUMENT:\n"
  "      return 0.0;\n"
  "    case AHUACATL_TYPEWEIGHT_BOOL:\n"
  "      return (value ? 1 : 0);\n"
  "    case AHUACATL_TYPEWEIGHT_NUMBER:\n"
  "      return value;\n"
  "    case AHUACATL_TYPEWEIGHT_STRING:\n"
  "      var result = parseFloat(value);\n"
  "      return ((AHUACATL_TYPEWEIGHT(result) === AHUACATL_TYPEWEIGHT_NUMBER) ? result : 0);\n"
  "  }\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief cast to a string\n"
  "///\n"
  "/// the operand can have any type, always returns a string\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_CAST_STRING (value) {\n"
  "  switch (AHUACATL_TYPEWEIGHT(value)) {\n"
  "    case AHUACATL_TYPEWEIGHT_STRING:\n"
  "      return value;\n"
  "    case AHUACATL_TYPEWEIGHT_NULL:\n"
  "      return 'null';\n"
  "    case AHUACATL_TYPEWEIGHT_BOOL:\n"
  "      return (value ? 'true' : 'false');\n"
  "    case AHUACATL_TYPEWEIGHT_NUMBER:\n"
  "    case AHUACATL_TYPEWEIGHT_LIST:\n"
  "    case AHUACATL_TYPEWEIGHT_DOCUMENT:\n"
  "      return value.toString();\n"
  "  }\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief cast to a bool\n"
  "///\n"
  "/// the operand can have any type, always returns a bool\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_CAST_BOOL (value) {\n"
  "  switch (AHUACATL_TYPEWEIGHT(value)) {\n"
  "    case AHUACATL_TYPEWEIGHT_NULL:\n"
  "      return false;\n"
  "    case AHUACATL_TYPEWEIGHT_BOOL:\n"
  "      return value;\n"
  "    case AHUACATL_TYPEWEIGHT_NUMBER:\n"
  "      return (value != 0);\n"
  "    case AHUACATL_TYPEWEIGHT_STRING: \n"
  "      return (value != '');\n"
  "    case AHUACATL_TYPEWEIGHT_LIST:\n"
  "      return (value.length > 0);\n"
  "    case AHUACATL_TYPEWEIGHT_DOCUMENT:\n"
  "      return (AHUACATL_KEYS(value).length > 0);\n"
  "  }\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief cast to null\n"
  "///\n"
  "/// the operand can have any type, always returns null\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_CAST_NULL (value) {\n"
  "  return null;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @}\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "// -----------------------------------------------------------------------------\n"
  "// --SECTION--                                               typecheck functions\n"
  "// -----------------------------------------------------------------------------\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @addtogroup Ahuacatl\n"
  "/// @{\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief test if value is of type string\n"
  "///\n"
  "/// returns a bool\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_IS_STRING (value) {\n"
  "  return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_STRING);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief test if value is of type number\n"
  "///\n"
  "/// returns a bool\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_IS_NUMBER (value) {\n"
  "  return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_NUMBER);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief test if value is of type bool\n"
  "///\n"
  "/// returns a bool\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_IS_BOOL (value) {\n"
  "  return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_BOOL);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief test if value is of type null\n"
  "///\n"
  "/// returns a bool\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_IS_NULL (value) {\n"
  "  return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_NULL);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief test if value is of type list\n"
  "///\n"
  "/// returns a bool\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_IS_LIST (value) {\n"
  "  return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_LIST);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief test if value is of type document\n"
  "///\n"
  "/// returns a bool\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_IS_DOCUMENT (value) {\n"
  "  return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_DOCUMENT);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @}\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "// -----------------------------------------------------------------------------\n"
  "// --SECTION--                                        high level query functions\n"
  "// -----------------------------------------------------------------------------\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @addtogroup Ahuacatl\n"
  "/// @{\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief sort the results\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_SORT (value, sortFunction) {\n"
  "  AHUACATL_LIST(value);\n"
  " \n"
  "  var n = value.length;\n"
  "  if (n > 0) {\n"
  "    value.sort(sortFunction);\n"
  "  }\n"
  "\n"
  "  return value;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief group the results\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_GROUP (value, sortFunction, groupFunction, into) {\n"
  "  AHUACATL_LIST(value);\n"
  "\n"
  "  var n = value.length;\n"
  "  if (n == 0) {\n"
  "    return [ ];\n"
  "  }\n"
  "\n"
  "  AHUACATL_SORT(value, sortFunction);\n"
  "\n"
  "  var result = [ ];\n"
  "  var currentGroup = undefined;\n"
  "  var oldGroup = undefined;\n"
  "  \n"
  "  for (var i = 0; i < n; ++i) {\n"
  "    var row = value[i];\n"
  "    var groupValue = groupFunction(row);\n"
  "\n"
  "    if (AHUACATL_RELATIONAL_UNEQUAL(oldGroup, groupValue)) {\n"
  "      oldGroup = AHUACATL_CLONE(groupValue);\n"
  "\n"
  "      if (currentGroup) {\n"
  "        result.push(AHUACATL_CLONE(currentGroup));\n"
  "      }\n"
  "      \n"
  "      currentGroup = groupValue;\n"
  "      if (into) {\n"
  "        currentGroup[into] = [ ];\n"
  "      }\n"
  "    }\n"
  "\n"
  "    if (into) {\n"
  "      currentGroup[into].push(AHUACATL_CLONE(row));\n"
  "    }\n"
  "  }\n"
  "\n"
  "  if (currentGroup) {\n"
  "    result.push(AHUACATL_CLONE(currentGroup));\n"
  "  }\n"
  "\n"
  "  return result;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief limit the number of results\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_LIMIT (value, offset, count) {\n"
  "  AHUACATL_LIST(value);\n"
  "\n"
  "  if (count < 0) {\n"
  "    throw \"negative count is not supported for limit\";\n"
  "  }\n"
  "\n"
  "  return value.slice(offset, offset + count);\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @brief get the length of a list\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
  "function AHUACATL_LENGTH (args) {\n"
  "  var value = args[0];\n"
  "\n"
  "  AHUACATL_LIST(value);\n"
  "\n"
  "  return value.length;\n"
  "}\n"
  "\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "/// @}\n"
  "////////////////////////////////////////////////////////////////////////////////\n"
  "\n"
;
